#include "FreeCamera.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <gl/GL.h>
#include <gl/GLU.h>
#include "SDL.h"
#include <cmath>
#include <iostream>

namespace steam
{
	namespace moon
	{

		FreeCamera::FreeCamera() : LookSpeed(0.005f), MoveSpeed(5.1f), 
			PitchClampInRadian(1.3962f), YawClampInRadian(6.2831f)/*,	m_MoveOnlyOnHorizontalPlane(false)*/
		{
			m_Position = base::Vector3(0.0f, 2.0f, 5.0f);
			m_AngleX = 0;
			m_AngleY = 0;
			keys[0] = keys[1] = keys[2] = keys[3] = false;
		}

		FreeCamera::FreeCamera(base::Vector3 position, float yawAngle, float pitchAngle) : LookSpeed(0.005f), MoveSpeed(0.5f), 
			PitchClampInRadian(1.3962f), YawClampInRadian(6.2831f)/*,	m_MoveOnlyOnHorizontalPlane(false)*/
		{
			m_Position = position;
			m_AngleX = (6.2831f * yawAngle) / 360.f;
			m_AngleY = 0;
			keys[0] = keys[1] = keys[2] = keys[3] = false;
		}

		FreeCamera::~FreeCamera()
		{
		}

		void FreeCamera::update()
		{
			float cameraY = m_Position.y;

			int midX = 320;
			int midY = 240;

			SDL_ShowCursor(SDL_DISABLE);

			int curX;
			int curY;

			SDL_GetMouseState(&curX, &curY);

			m_AngleX -= (curX - midX) * LookSpeed;
			m_AngleY -= (curY - midY) * LookSpeed;

			SDL_WarpMouse(midX, midY);

			if (m_AngleX > YawClampInRadian)
				m_AngleX -= YawClampInRadian;

			if (m_AngleX < 0.0)
				m_AngleX += YawClampInRadian;
			if(m_AngleY > PitchClampInRadian)
				m_AngleY = PitchClampInRadian;

			if(m_AngleY < -PitchClampInRadian)
				m_AngleY = -PitchClampInRadian;

			// Get forward vector
			m_Forward = base::Vector3(
				cos(m_AngleY) * sin(m_AngleX), 
				sin(m_AngleY),
				cos(m_AngleY) * cos(m_AngleX)
			);

			// Get right vector
			m_Right = base::Vector3(
				sin(m_AngleX - 3.14f/2.0f), 
				0,
				cos(m_AngleX - 3.14f/2.0f)
			);

			// Get up vector
			m_Up = m_Right.cross(m_Forward);

// 			if (m_MoveOnlyOnHorizontalPlane) {
// 				m_Position.y = cameraY;
// 			}

			if (keys[0]) m_Position += m_Forward * MoveSpeed;
			else if (keys[1]) m_Position -= m_Forward * MoveSpeed;
			if (keys[2]) m_Position -= m_Right * MoveSpeed;
			else if (keys[3]) m_Position += m_Right * MoveSpeed;

			base::Vector3 lookAt = m_Position + m_Forward;
			gluLookAt(m_Position.x, m_Position.y, m_Position.z,
				lookAt.x, lookAt.y, lookAt.z, m_Up.x, m_Up.y, m_Up.z);

		}

// 		void FreeCamera::setMoveOnlyOnHorizontalPlane(bool flag)
// 		{
// 			m_MoveOnlyOnHorizontalPlane = flag;
// 		}

		const base::Vector3& FreeCamera::getPosition() const
		{
			return m_Position;
		}

		const base::Vector3& FreeCamera::getForward() const
		{
			return m_Forward;
		}

		void FreeCamera::init(base::Vector3 position, float yawAngle, float pitchAngle)
		{
			m_Position = position;
			m_AngleX = (6.2831f * yawAngle) / 360.f;
			m_AngleY = (6.2831f * pitchAngle) / 360.f;
		}

		void FreeCamera::keyPressed( const intake::KeyEvent* evt )
		{
			if (evt)
			{
				if (evt->getKeyCode() == intake::SK_W)
				{
					keys[0] = true;
				}
				else if (evt->getKeyCode() == intake::SK_S)
				{
					keys[1] = true;
				}
				
				if (evt->getKeyCode() == intake::SK_A)
				{
					keys[2] = true;
				}
				else if (evt->getKeyCode() == intake::SK_D)
				{
					keys[3] = true;
				}
			}
		}

		void FreeCamera::keyReleased( const intake::KeyEvent* evt )
		{
			if (evt)
			{
				if (evt->getKeyCode() == intake::SK_W)
				{
					keys[0] = false;
				}
				else if (evt->getKeyCode() == intake::SK_S)
				{
					keys[1] = false;
				}

				if (evt->getKeyCode() == intake::SK_A)
				{
					keys[2] = false;
				}
				else if (evt->getKeyCode() == intake::SK_D)
				{
					keys[3] = false;
				}
			}
		}

	}
	
}